﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
using ServiceConfigurator.Properties;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.Win32;
using System.IO;
using System.Diagnostics;

namespace ServiceConfigurator
{
	public partial class ConfigurationMain : Form
	{
		public ConfigurationMain()
		{
			InitializeComponent();
			if ( File.Exists(Path.Combine(Application.StartupPath, "OpenComposite.exe")) ) {
				string installDir = Path.GetDirectoryName(Application.StartupPath);
				if ( Directory.Exists(Path.Combine(installDir, "Data Service")) ) {
					txtSvcConfigPath.Text = installDir;
					displaySvcConfig();
				}
			}
			if ( string.IsNullOrEmpty(txtSvcConfigPath.Text) ) {
				RegistryKey key = null;
				try {
					// try old install registry first!
					key = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("OpenComposite Team");
					if ( key != null ) {
						object obj = key.GetValue(null);
						if ( obj != null ) {
							txtSvcConfigPath.Text = obj.ToString();
							displaySvcConfig();
						} else { Trace.WriteLine("'SOFTWRE/OpenComposite Team/(Default)' not found"); }
					} else { Trace.WriteLine("'SOFTWRE/OpenComposite Team' not found"); }
					if ( string.IsNullOrEmpty(txtSvcConfigPath.Text) ) {
						key = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("OpenComposite Team").OpenSubKey("OpenComposite");
						if ( key != null ) {
							object obj = key.GetValue("InstallPath");
							if ( obj != null ) {
								txtSvcConfigPath.Text = obj.ToString();
								displaySvcConfig();
							} else { Trace.WriteLine("'SOFTWRE/OpenComposite Team/OpenComposite/InstallDir' not found"); }
						} else {
							key = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("OpenComposite Team").OpenSubKey("OpenComposite");
							if ( key != null ) {
								object obj = key.GetValue("InstallPath");
								if ( obj != null ) {
									txtSvcConfigPath.Text = obj.ToString();
									displaySvcConfig();
								} else { Trace.WriteLine("'SOFTWRE/OpenComposite Team/OpenComposite/InstallDir' not found"); }
							} else { Trace.WriteLine("'SOFTWRE/OpenComposite Team/OpenComposite' not found"); }
						}
					}
				} catch ( Exception ex ) { Trace.WriteLine(ex.Message); }
			}
			updateStatusTimer.Start();
			checkServiceStatus();
		}

		private Configuration _hActSvcConfig = null;
		//private Configuration _dataSvcConfig = null;
		//private ServiceController _dataSvcController = null;
		private bool _dataSvcRestarting = false;
		private ServiceController _hActSvcController = null;
		private bool _hActSvcRestarting = false;
		private AboutServiceConfigurator _about = new AboutServiceConfigurator();

		#region Service Status Images
		Image _serviceRunningImage = null;
		Image _serviceStoppedImage = null;
		Image _servicePendingImage = null;

		private Image SvcRunningImage
		{
			get
			{
				if ( _serviceRunningImage == null ) {
					_serviceRunningImage = Resources.servicerunning;
				}
				return _serviceRunningImage;
			}
		}
		private Image SvcStoppedImage
		{
			get
			{
				if ( _serviceStoppedImage == null ) {
					_serviceStoppedImage = Resources.servicestopped;
				}
				return _serviceStoppedImage;
			}
		}
		private Image SvcPendingImage
		{
			get
			{
				if ( _servicePendingImage == null ) {
					_servicePendingImage = Resources.serviceunknown;
				}
				return _servicePendingImage;
			}
		}
		#endregion

		private void ConfigurationMain_FormClosing(object sender, FormClosingEventArgs e)
		{

		}

		private void checkServiceStatus()
		{
			//_dataSvcController = new ServiceController("OpenCompositeDataService");
			//try {
			//    changeDataSvcStatus(_dataSvcController.Status);
			//} catch { }
			_hActSvcController = new ServiceController("OpenCompositeHAService");
			try {
				changeHASvcStatus(_hActSvcController.Status);
			} catch { }
		}

		//private void changeDataSvcStatus(ServiceControllerStatus status)
		//{
		//    if ( _dataSvcRestarting ) {
		//        if ( status == ServiceControllerStatus.Stopped )
		//            _dataSvcController.Start();
		//        if ( _dataSvcController.Status != ServiceControllerStatus.Running )
		//            return;
		//    }
		//    switch ( status ) {
		//        case ServiceControllerStatus.ContinuePending:
		//            lblDataSvcStatus.Text = "Status: Pending";
		//            btnStartStopDataSvc.Text = "...";
		//            btnStartStopHASvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Enabled = false;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        case ServiceControllerStatus.PausePending:
		//            lblDataSvcStatus.Text = "Status: Pending";
		//            btnStartStopDataSvc.Text = "...";
		//            btnStartStopHASvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Enabled = false;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        case ServiceControllerStatus.Paused:
		//            lblDataSvcStatus.Text = "Status: Pending";
		//            btnStartStopDataSvc.Text = "...";
		//            btnStartStopHASvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Enabled = false;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        case ServiceControllerStatus.Running:
		//            lblDataSvcStatus.Text = "Status: Running";
		//            btnStartStopDataSvc.Text = "Stop";
		//            btnStartStopDataSvc.Image = SvcRunningImage;
		//            btnStartStopDataSvc.Enabled = true;
		//            btnRestartDataSvc.Enabled = true;
		//            if ( _dataSvcRestarting ) {
		//                _dataSvcRestarting = false;
		//                MessageBox.Show("Data Service restarted successfully!",
		//                    "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
		//            }
		//            break;
		//        case ServiceControllerStatus.StartPending:
		//            lblDataSvcStatus.Text = "Status: Pending";
		//            btnStartStopDataSvc.Text = "...";
		//            btnStartStopHASvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Enabled = false;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        case ServiceControllerStatus.StopPending:
		//            lblDataSvcStatus.Text = "Status: Pending";
		//            btnStartStopDataSvc.Text = "...";
		//            btnStartStopHASvc.Image = SvcPendingImage;
		//            btnStartStopDataSvc.Enabled = false;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        case ServiceControllerStatus.Stopped:
		//            lblDataSvcStatus.Text = "Status: Stopped";
		//            btnStartStopDataSvc.Text = "Start";
		//            btnStartStopDataSvc.Image = SvcStoppedImage;
		//            btnStartStopDataSvc.Enabled = true;
		//            btnRestartDataSvc.Enabled = false;
		//            break;
		//        default:
		//            break;
		//    }
		//}

		private void changeHASvcStatus(ServiceControllerStatus status)
		{
			if ( _hActSvcRestarting ) {
				if ( status == ServiceControllerStatus.Stopped )
					_hActSvcController.Start();
				if ( _hActSvcController.Status != ServiceControllerStatus.Running )
					return;
			}
			switch ( status ) {
				case ServiceControllerStatus.ContinuePending:
					lblHASvcStatus.Text = "Status: Pending";
					btnStartStopHASvc.Text = "...";
					btnStartStopHASvc.Image = SvcPendingImage;
					btnStartStopHASvc.Enabled = false;
					btnRestartHASvc.Enabled = false;
					break;
				case ServiceControllerStatus.PausePending:
					lblHASvcStatus.Text = "Status: Pending";
					btnStartStopHASvc.Text = "...";
					btnStartStopHASvc.Image = SvcPendingImage;
					btnStartStopHASvc.Enabled = false;
					btnRestartHASvc.Enabled = false;
					break;
				case ServiceControllerStatus.Paused:
					lblHASvcStatus.Text = "Status: Pending";
					btnStartStopHASvc.Text = "...";
					btnStartStopHASvc.Image = SvcPendingImage;
					btnStartStopHASvc.Enabled = false;
					btnRestartHASvc.Enabled = false;
					break;
				case ServiceControllerStatus.Running:
					lblHASvcStatus.Text = "Status: Running";
					btnStartStopHASvc.Text = "Stop";
					btnStartStopHASvc.Image = SvcRunningImage;
					btnStartStopHASvc.Enabled = true;
					btnRestartHASvc.Enabled = true;
					if ( _hActSvcRestarting ) {
						_hActSvcRestarting = false;
						MessageBox.Show("Human Activity Service restarted successfully!",
							"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
					}
					break;
				case ServiceControllerStatus.StartPending:
					lblHASvcStatus.Text = "Status: Pending";
					btnStartStopHASvc.Text = "...";
					btnStartStopHASvc.Image = SvcPendingImage;
					btnStartStopHASvc.Enabled = false;
					btnRestartHASvc.Enabled = false;
					break;
				case ServiceControllerStatus.StopPending:
					lblHASvcStatus.Text = "Status: Pending";
					btnStartStopHASvc.Text = "...";
					btnStartStopHASvc.Image = SvcPendingImage;
					btnStartStopHASvc.Enabled = false;
					btnRestartHASvc.Enabled = false;
					break;
				case ServiceControllerStatus.Stopped:
					lblHASvcStatus.Text = "Status: Stopped";
					btnStartStopHASvc.Text = "Start";
					btnStartStopHASvc.Image = SvcStoppedImage;
					btnStartStopHASvc.Enabled = true;
					btnRestartHASvc.Enabled = false;
					break;
				default:
					break;
			}
		}

		private void displaySvcConfig()
		{
			ExeConfigurationFileMap haSvcMap = new ExeConfigurationFileMap();
			haSvcMap.ExeConfigFilename = Path.Combine(txtSvcConfigPath.Text, Path.Combine("Human Activity Service", "OpenComposite.HumanActivity.Service.exe.config")); ;
			_hActSvcConfig = ConfigurationManager.OpenMappedExeConfiguration(haSvcMap, ConfigurationUserLevel.None);
			ConnectionStringSettings setting = _hActSvcConfig.ConnectionStrings.ConnectionStrings["OpenComposite.HumanActivity.Properties.Settings.ConnectionString"];
			if ( setting == null ) {
				MessageBox.Show("The Human Activity Service could not be found in the installation directory. Please select the correct directory",
					"Configuration Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				tsbtnSave.Enabled = false;
				return;
			}
			tsbtnSave.Enabled = true;
			string connString = setting.ConnectionString;
			SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder(connString);
			txtSvcDBServer.Text = connBuilder.DataSource;
			txtSvcDBName.Text = connBuilder.InitialCatalog;
			cbxSvcWinAuth.Checked = connBuilder.IntegratedSecurity;
			if ( !connBuilder.IntegratedSecurity ) {
				txtSvcDBUser.Text = connBuilder.UserID;
				txtSvcDBPassword.Text = connBuilder.Password;
			}
		}

		private void saveSvcConfig()
		{

			SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder();
			connBuilder.DataSource = txtSvcDBServer.Text;
			connBuilder.InitialCatalog = txtSvcDBName.Text;
			connBuilder.IntegratedSecurity = cbxSvcWinAuth.Checked;
			connBuilder.PersistSecurityInfo = !cbxSvcWinAuth.Checked;
			if ( !cbxSvcWinAuth.Checked ) {
				connBuilder.UserID = txtSvcDBUser.Text;
				connBuilder.Password = txtSvcDBPassword.Text;
			}
			SqlConnection conn = new SqlConnection(connBuilder.ConnectionString);
			try {
				conn.Open();
			} catch ( SqlException ex ) {
				string msg = string.Format("The connection to the database could not be established.{0}The following error occured:{0}{1}{0}{0} Do you want to continue?", Environment.NewLine, ex.Message);
				if ( MessageBox.Show(msg, "Connection error",
									 MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No )
					return;
			} finally {
				conn.Close();
			}

			DialogResult result = MessageBox.Show("This will overwrite the settings of Data Service and Human Activity Service. (You have to restart both services after saving, to apply the changes)" + Environment.NewLine + "Do you want to continue?",
				"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			if ( result == DialogResult.No ) return;

			bool saveOk = true;
			//if ( _dataSvcConfig != null ) {
			//    ConnectionStringSettings setting = _dataSvcConfig.ConnectionStrings.ConnectionStrings["OpenComposite.Properties.Settings.ConnectionString"];
			//    if ( setting != null ) {
			//        setting.ConnectionString = connBuilder.ConnectionString;
			//        _dataSvcConfig.Save();
			//    } else { saveOk = false; }
			//}
			if ( _hActSvcConfig != null ) {
				ConnectionStringSettings setting = _hActSvcConfig.ConnectionStrings.ConnectionStrings["OpenComposite.HumanActivity.Properties.Settings.ConnectionString"];
				if ( setting != null ) {
					setting.ConnectionString = connBuilder.ConnectionString;
					_hActSvcConfig.Save();
				} else { saveOk = false; }
			}
			if ( !saveOk ) {
				MessageBox.Show("An error occured while saving. Check if the installation path is correct!", "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		#region Event Handlers

		//private void btnStartStopDataSvc_Click(object sender, EventArgs e)
		//{
		//    if ( _dataSvcController == null ) return;
		//    if ( _dataSvcController.Status == ServiceControllerStatus.Stopped ) {
		//        _dataSvcController.Start();
		//    } else if ( _dataSvcController.Status == ServiceControllerStatus.Running ) {
		//        _dataSvcController.Stop();
		//    }
		//    checkServiceStatus();
		//}

		private void btnStartStopHASvc_Click(object sender, EventArgs e)
		{
			if ( _hActSvcController == null ) return;
			if ( _hActSvcController.Status == ServiceControllerStatus.Stopped ) {
				_hActSvcController.Start();
			} else if ( _hActSvcController.Status == ServiceControllerStatus.Running ) {
				_hActSvcController.Stop();
			}
		}

		private void updateStatusTimer_Tick(object sender, EventArgs e)
		{
			checkServiceStatus();
		}

		private void btnChangeSvcConfigPath_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog dlg = new FolderBrowserDialog();
			dlg.Description = "Please select the installation directory containing the Data Service and Human Activity Service folders.";
			dlg.SelectedPath = txtSvcConfigPath.Text;
			if ( dlg.ShowDialog() == DialogResult.OK ) {
				txtSvcConfigPath.Text = dlg.SelectedPath;
				displaySvcConfig();
			}
		}

		private void tsbtnSave_Click(object sender, EventArgs e)
		{
			saveSvcConfig();
		}

		private void btnRestartHASvc_Click(object sender, EventArgs e)
		{
			if ( _hActSvcController == null ) return;
			if ( _hActSvcController.Status == ServiceControllerStatus.Stopped ) {
				_hActSvcController.Start();
			} else if ( _hActSvcController.Status == ServiceControllerStatus.Running ) {
				_hActSvcController.Stop();
			}
			checkServiceStatus();
			_hActSvcRestarting = true;

		}

		//private void btnRestartDataSvc_Click(object sender, EventArgs e)
		//{
		//    if ( _dataSvcController == null ) return;
		//    if ( _dataSvcController.Status == ServiceControllerStatus.Stopped ) {
		//        _dataSvcController.Start();
		//    } else if ( _dataSvcController.Status == ServiceControllerStatus.Running ) {
		//        _dataSvcController.Stop();
		//    }
		//    checkServiceStatus();
		//    _dataSvcRestarting = true;
		//}

		private void cbxSvcWinAuth_CheckedChanged(object sender, EventArgs e)
		{
			txtSvcDBUser.Enabled = !cbxSvcWinAuth.Checked;
			txtSvcDBPassword.Enabled = !cbxSvcWinAuth.Checked;
		}

		private void lnkTestConnection_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder();
			connBuilder.DataSource = txtSvcDBServer.Text;
			connBuilder.InitialCatalog = txtSvcDBName.Text;
			connBuilder.IntegratedSecurity = cbxSvcWinAuth.Checked;
			if ( !cbxSvcWinAuth.Checked ) {
				connBuilder.UserID = txtSvcDBUser.Text;
				connBuilder.Password = txtSvcDBPassword.Text;
			}
			SqlConnection conn = new SqlConnection(connBuilder.ConnectionString);
			try {
				this.Cursor = Cursors.WaitCursor;
				conn.Open();
				MessageBox.Show("The connection could be established!",
					"Test Connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
			} catch ( Exception ex ) {
				MessageBox.Show(string.Format("The connection could not be established!{0}{0}{1}", Environment.NewLine, ex.Message),
					"Test Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			} finally {
				this.Cursor = Cursors.Default;
				conn.Close();
			}
		}

		private void ConfigurationMain_KeyUp(object sender, KeyEventArgs e)
		{
			if ( e.KeyCode == Keys.F1 ) {
				_about.ShowDialog();
			}
		}

		#endregion
	}
}
